﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace Lizk.Media
{
    public class TVScanner : TypeScanner
    {
        public bool SortSeasons { get; set; }
        public string SeasonString { get; set; }
        public TVScanner(string type)
            : base(type)
        {
            SeasonString = "Season {0}";
        }


        public override void Scan(string rootPath, Predicate<VideoData> exists, Action<VideoData> mediaAdded)
        {
            string volumeLabel = new DriveInfo(rootPath).VolumeLabel;
            string rootPathString = rootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) ? rootPath : rootPath + Path.DirectorySeparatorChar;

            foreach (var titleDir in Directory.GetDirectories(Path.Combine(rootPath, this.Type)))
            {
                string titleName = Path.GetFileName(titleDir);
                if (titleName.StartsWith("."))
                    continue;

                string image = MediaUtil.FindImage(titleDir, PictureExtensions);
                if (image != null)
                    image = image.Replace(rootPathString, "");

                foreach (string file in Directory.GetFiles(titleDir, "*.*", SearchOption.AllDirectories))
                {
                    string format;
                    if ((format = GetVideoType(Path.GetFileName(file))) == null)
                        continue;


                    string path = file.Replace(rootPathString, "");

                    VideoData v = new VideoData();
                    v.path = path;
                    v.volume = volumeLabel;

                    if (exists == null || !exists(v))
                    {
                        FileInfo f = new FileInfo(file);

                        if (format == "media")
                            VideoData.ParseTVShowFilename(v, file);

                        v.mimetype = MediaUtil.GetMimeType(f.Extension.Substring(1));
                        v.filesize = f.Length;
                        v.title = v.show = titleName;
                        v.type = this.Type;
                        v.lastmodified = f.CreationTime.ToFileTime();
                        v.format = format;
                        v.artwork = image != null ? image : "";

                        if (v.episode > 0 && v.season > 0 && SortSeasons)
                        {
                            v.title = v.show + " " + v.season + "x" + v.episode.ToString().PadLeft(2, '0');
                            string newPath = MoveTVShow(titleDir, file, v);
                            if (newPath != file)
                                v.path = newPath.Replace(rootPathString, "");
                        }
                        else
                            v.title = Path.GetFileNameWithoutExtension(file);

                        mediaAdded(v);
                    }
                }
            }

        }
        protected string MoveTVShow(string showDir, string path, VideoData v)
        {
            //string tail = v.comment;// Regex.Replace(v.comment, @"(?i)[^A-Z0-9 \+=']+", " ").Trim().Replace(' ', '.').ToLower();
            string tail = v.comment;

            Match m = Regex.Match(tail, @"(?i)^[_\-\. ]*(.*?)[_\-\. ]*$");
            if (m.Success)
                tail = m.Groups[1].Value;
            if (tail.Length > 0) tail = "." + tail.Trim();

            string lastEpisode = v.lastepisode > v.episode ? "-" + v.lastepisode.ToString().PadLeft(2, '0') : "";

            string newName = v.show + "." + "s" + v.season.ToString().PadLeft(2, '0') + "e" + v.episode.ToString().PadLeft(2, '0') + lastEpisode + tail + Path.GetExtension(path);
            newName = Regex.Replace(newName, @"\s+", ".");
            string newPath = showDir + Path.DirectorySeparatorChar + string.Format(SeasonString, v.season) + Path.DirectorySeparatorChar + newName;
            string newRelatedPath;
            if (path.ToLower().Equals(newPath.ToLower()))
                return path;

           
            try
            {
                if (File.Exists(newPath))
                    newPath = showDir + Path.DirectorySeparatorChar + newName;

                if (!File.Exists(newPath))
                {
                    if (!Directory.Exists(Path.GetDirectoryName(newPath)))
                        Directory.CreateDirectory(Path.GetDirectoryName(newPath));

                    File.Move(path, newPath);
                    foreach (string relatedPath in MediaUtil.RelatedFiles(path))
                    {
                        if (GetVideoType(relatedPath) != null)
                            continue;

                        newRelatedPath = Path.ChangeExtension(newPath, Path.GetExtension(relatedPath));
                        if (!File.Exists(newRelatedPath))
                            File.Move(relatedPath, newRelatedPath);
                    }
                }
            }
            catch
            {
                return path;
            }
            return newPath;
        }

    }
}
